<template>
  <div class="waterfall-container">
    <div v-for="item in list" :key="item.id" class="history-card-item">
      <div class="card-media">
        <Video
          v-if="item.videoUrl"
          :key="item.videoUrl"
          :src="changeProtocol(item.videoUrl)"
          class="card-video"
          @error="handleError($event, item)"
        ></Video>
        <div v-else-if="getFailMessage(item)" class="card-placeholder">
          <span class="err-msg">{{ getFailMessage(item) }}</span>
        </div>
        <div
          v-else-if="item.picUrl"
          class="card-placeholder"
          :style="{ backgroundImage: `url(${changeProtocol(item.picUrl)})` }"
        ></div>
        <div v-else class="card-placeholder">
          <el-icon :size="64">
            <VideoCamera />
          </el-icon>
        </div>
        <div class="card-status-badge">
          <el-tag type="success" v-if="isCase">演示案例</el-tag>
          <el-tag type="success" v-else-if="item.status === 2">已完成</el-tag>
          <el-tag type="warning" v-else-if="item.status === 1">生成中</el-tag>
          <el-tag type="danger" v-else-if="item.status === 3">生成失败</el-tag>
          <el-tag type="info" v-else-if="item.status === 0">新建</el-tag>
        </div>
      </div>
      <div class="card-info">
        <div class="card-type">
          <div class="tags">
            <el-tag type="primary" size="small" v-if="item.taskType === 2"
              >图片生成视频</el-tag
            >
            <el-tag type="success" size="small" v-else-if="item.taskType === 1"
              >文案生成视频</el-tag
            >
            <el-tag type="warning" size="small" style="margin-left: 4px"
              >{{ item.seconds }}秒</el-tag
            >
          </div>
          <span class="meta-item">{{ item.createTime }}</span>
        </div>
        <div class="card-description" :title="item.des" @click="copyDes(item)">
          {{ item.des }}
        </div>
        <div class="card-actions">
          <el-button-group class="card-button-group">
            <template v-if="isCase">
              <el-button
                type="primary"
                icon="Edit"
                class="cardButton"
                :loading="item.loading"
                @click="handleEdit(item)"
                size="large"
              >
                我要复刻
              </el-button>
            </template>
            <template v-else-if="item.videoUrl">
              <el-button
                type="primary"
                icon="CopyDocument"
                class="cardButton"
                @click="copyUrl(item)"
                size="large"
              >
                复制
              </el-button>
              <el-button
                type="primary"
                icon="Download"
                class="cardButton"
                :loading="item.loading"
                @click="downloadFile(item)"
                size="large"
              >
                <span v-if="item.loading">
                  <template v-if="item.progress === -1">下载失败</template>
                  <template v-else-if="item.progress === 100"
                    >下载完成</template
                  >
                  <template v-else>下载中 {{ item.progress }}%</template>
                </span>
                <span v-else>下载(极速)</span>
              </el-button>
              <el-button
                v-if="!item.useBackUp"
                type="primary"
                icon="QuestionFilled"
                class="cardButton"
                size="large"
                @click="useBackUpUrl(item)"
                >下载异常</el-button
              >

              <el-button
                type="primary"
                icon="Download"
                class="cardButton"
                :loading="item.loadingCn"
                v-if="item.useBackUp"
                @click="downloadFileCn(item)"
                size="large"
              >
                <span v-if="item.loadingCn">
                  <template v-if="item.progressCn === -1">下载失败</template>
                  <template v-else-if="item.progressCn === 100"
                    >下载完成</template
                  >
                  <template v-else>下载中 {{ item.progressCn }}%</template>
                </span>
                <span v-else>下载(备用)</span>
              </el-button>
            </template>
            <template v-if="item.status === 3">
              <el-button
                type="primary"
                icon="Edit"
                class="cardButton"
                :loading="item.loading"
                @click="handleEdit(item)"
                size="large"
              >
                重新编辑
              </el-button>
              <el-button
                type="danger"
                icon="Delete"
                class="cardButton"
                :loading="item.loading"
                @click="handleDelete(item)"
                size="large"
              >
                删除
              </el-button>
            </template>
          </el-button-group>
        </div>
        <div class="card-tips" v-if="item.videoUrl">视频保留2天,请尽快下载</div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import Video from './Video.vue';
import { copy } from 'clipboard';
import { ElMessageBox } from 'element-plus';
import { deleteTask } from '../../api/task';
import FileSaver from 'file-saver';
import { changeProtocol } from '../../utils/ruoyi';
import axios from 'axios';
import { downloadVideo } from '@/api/work/userVip.js';

defineProps({
  list: {
    type: Array,
    default: () => [],
  },
  isCase: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(['refresh']);

const router = useRouter();

// 错误处理函数
const handleError = async (error, item) => {
  let errorMessage = '';
  if (!error) {
    return;
  }
  if (error?.code) {
    // 根据错误代码显示错误信息
    switch (error?.code) {
      case 1: // MEDIA_ERR_ABORTED
        errorMessage = '视频加载被中止';
        break;
      case 2: // MEDIA_ERR_NETWORK
        errorMessage = '网络错误，请检查网络连接';
        break;
      case 3: // MEDIA_ERR_DECODE
        errorMessage = '视频解码错误';
        break;
      case 4: // MEDIA_ERR_SRC_NOT_SUPPORTED
        errorMessage = '视频格式不支持或源地址错误';
        break;
      default:
        errorMessage = '视频加载出错，请稍后重试';
    }
  }
  console.log('...... > handleError > errorMessage:', errorMessage);
  if (item.videoUrlChanged) {
    return;
  }
  item.videoUrlChanged = true;
  const res = await downloadVideo({ id: item.id });
  item.oldVideoUrl = item.videoUrl;
  item.videoUrl = res.data;
};

const getFailMessage = (item) => {
  if (!item.failMsg) {
    return '';
  }
  try {
    /** @type {string} */
    const failReason = JSON.parse(item.failMsg)?.message || '';
    if (failReason.includes('photorealistic people')) {
      return '暂不支持上传人像图片，请选择风景、物品、动物等内容';
    }
    return failReason;
  } catch (error) {
    return '';
  }
};

const useBackUpUrl = (item) => {
  ElMessageBox.confirm('是否使用备份链接下载？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      item.useBackUp = true;
    })
    .catch(() => {});
};
const downloadFileCn = async (item) => {
  if (!item.videoUrl) {
    ElMessage.error('视频地址不存在，无法下载！');
    return;
  }
  ElMessage.info('开始下载...');
  item.loadingCn = true;
  item.progressCn = 0;
  const res = await downloadVideo({ id: item.id });
  item.oldVideoUrl = item.videoUrl;
  item.videoUrl = res.data;

  const response = await axios
    .get(changeProtocol(item.videoUrl), {
      responseType: 'blob',
      onDownloadProgress: (progressEvent) => {
        item.progressCn = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total,
        );
        if (!item.progressCn) {
          item.progressCn = 0;
        } else if (item.progress > 100) {
          item.progressCn = 100;
        }
      },
    })
    .catch((error) => {
      item.progressCn = -1;
      return Promise.reject(error);
    })
    .finally(() => {
      setTimeout(() => {
        item.loadingCn = false;
        item.progressCn = 0;
      }, 2000);
    });
  FileSaver.saveAs(response.data, item.videoUrl.split('/').pop() || '视频.mp4');
};
const downloadFile = async (item) => {
  if (!item.videoUrl) {
    ElMessage.error('视频地址不存在，无法下载！');
    return;
  }
  ElMessage.info('开始下载...');
  item.loading = true;
  item.progress = 0;
  const response = await axios
    .get(changeProtocol(item.videoUrl), {
      responseType: 'blob',
      onDownloadProgress: (progressEvent) => {
        item.progress = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total,
        );
        if (!item.progress) {
          item.progress = 0;
        } else if (item.progress > 100) {
          item.progress = 100;
        }
      },
    })
    .catch((error) => {
      item.progress = -1;
      return Promise.reject(error);
    })
    .finally(() => {
      setTimeout(() => {
        item.loading = false;
        item.progress = 0;
      }, 2000);
    });
  FileSaver.saveAs(response.data, item.videoUrl.split('/').pop() || '视频.mp4');
};

const handleDelete = async (item) => {
  await ElMessageBox.confirm('是否删除此记录?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  });
  item.loading = true;
  await deleteTask({ id: item.id }).finally(() => {
    item.loading = false;
  });
  emit('refresh');
};

const handleEdit = (item) => {
  const type = item.taskType === 2 ? 'pic' : 'text';
  router.push({
    path: `/${type}`,
    state: item,
  });
};

const copyUrl = (item) => {
  if (!item.videoUrl) {
    ElMessage.error('视频地址不存在，无法复制！');
    return;
  }
  copy(changeProtocol(item.videoUrl));
  ElMessage.success('视频地址已复制到剪贴板');
};

const copyDes = (item) => {
  if (!item.des) {
    ElMessage.error('描述内容不存在，无法复制！');
    return;
  }
  copy(changeProtocol(item.des));
  ElMessage.success('描述内容已复制到剪贴板');
};
</script>
<style scoped lang="scss">
.waterfall-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 24px;
}

.history-card-item {
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px #00000014;
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
}

.card-media {
  position: relative;
  width: 100%;
  padding-top: 181.78%;
  background: #f5f5f5;
  overflow: hidden;
}

.card-video {
  cursor: pointer;
}

.card-video,
.card-image,
.card-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.card-placeholder {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px;
}

.card-status-badge {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
}

.status-tag {
  font-weight: 600;
  border: none;
  box-shadow: 0 2px 8px #00000026;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-tag-green {
  color: #389e0d;
  background: #f6ffed;
  border-color: #b7eb8f;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-tag,
:where(.css-dev-only-do-not-override-1p3hq3p).ant-tag a,
:where(.css-dev-only-do-not-override-1p3hq3p).ant-tag a:hover {
  color: rgba(0, 0, 0, 0.88);
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-tag {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  color: rgba(0, 0, 0, 0.88);
  font-size: 12px;
  line-height: 20px;
  list-style: none;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
    'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  display: inline-block;
  height: auto;
  margin-inline-end: 8px;
  padding-inline: 7px;
  white-space: nowrap;
  background: rgba(0, 0, 0, 0.02);
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  opacity: 1;
  transition: all 0.2s;
  text-align: start;
}

:where(.css-dev-only-do-not-override-1p3hq3p)[class^='ant-tag'],
:where(.css-dev-only-do-not-override-1p3hq3p)[class*=' ant-tag'] {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
    'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  font-size: 14px;
  box-sizing: border-box;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-layout,
:where(.css-dev-only-do-not-override-1p3hq3p).ant-layout * {
  box-sizing: border-box;
}

.card-info {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: relative;
}

.card-type {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .tags {
    :deep(.el-tag) {
      padding-left: 2px;
      padding-right: 2px;
    }
  }
}

.card-description {
  font-size: 14px;
  font-weight: 500;
  color: #262626;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 42px;
  cursor: pointer;
  &:hover {
    color: var(--el-color-primary);
  }
}

.card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 12px;
  color: #8c8c8c;
}

.card-actions {
  display: flex;
}

.card-button-group {
  width: 100%;
  display: flex;
}

.cardButton {
  box-shadow: 0 2px 8px #1890ff4d;
  flex: auto;
  width: 1px;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: #8c8c8c;
}

.empty-box {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300px;
}

.err-msg {
  color: var(--el-color-danger);
}

.card-tips {
  color: var(--el-color-danger);
  font-size: 12px;
  text-align: right;
}
</style>
